﻿using ExchangeClient.Abstractions;
using ExchangeClient.Abstractions.Model;
using SyncService.Abstractions.Services;
using SyncService.Core.Model;
using SyncService.Core.Utils;
using System;
using System.Collections.Generic;
using System.Composition;
using System.Linq;
using System.Text;
using System.Text.Json.Nodes;
using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Logging;
using NPOI.XWPF.UserModel;
using NLog.Fluent;
using NPOI.SS.Formula.Functions;

namespace SyncService.Core.Services
{
    [Export(typeof(ISyncService))]
    [ExportMetadata(YdConstants.ID, "updateBill")]
    public class UpdateBillService : SyncServiceBase
    {
        protected override string NotifyGroupName => "";

        private bool IsNotPush = false;
        private ILogger<UpdateBillService> _logger = null;
        public UpdateBillService() : base("Esb", "Sap", "")
        {
        }
        protected override void InitializeContext()
        {
            base.InitializeContext();
            _logger = Resolver.Resolve<ILogger<UpdateBillService>>();
        }
        public override void Execute(dynamic? state)
        {
            ToClient.Callback = new Action<CallbackData>(YideaClient.CallbackHander);
            RequestData requestData = state;
            var form = requestData.EventId.Substring(0, 3);
            _logger.LogInformation("更新状态esb状态：1" );
            if (form == "upd")//处理更新单据
            {
                _logger.LogInformation("更新状态esb状态：2");
                UpdateFormState(requestData!.Body);
            }
          
        }
        private void UpdateFormState(string body)
        {
            _logger.LogInformation("更新状态："+body);
            UpdateBillModel? data = JsonSerializer.Deserialize<UpdateBillModel>(body);
            if (data != null)
            {
                var billType = data.billNo.Substring(0, 3);
                Guid formId = Guid.NewGuid();
                int sourceType = 0;
                var form = UserDefines.First(x => x.Name == "报废自定义表单");
                switch (billType)
                {
                    //报废
                    case "CLN":
                        form = UserDefines.First(x => x.Name == "报废自定义表单");

                        sourceType = 48;
                        break;

                    case "TRA":
                        form = UserDefines.First(x => x.Name == "调拨自定义表单");
                        sourceType = 49;
                        break;

                    case "NTR":
                        form = UserDefines.First(x => x.Name == "V测试资产调拨单");
                        sourceType = 60;
                        break;
                    //盘点单
                    case "AIN":
                        sourceType = 51;
                        IsNotPush = true;
                        break;
                    //发票登记单
                    case "IEF":

                        form = UserDefines.First(x => x.Name == "发票登记自定义表单");
                        sourceType = 50;
                        break;
                    //入库单
                    case "AIS":
                        IsNotPush = true;
                        form = UserDefines.First(x => x.Name == "发票登记自定义表单");
                        sourceType = 55;
                        break;
                    case "ZER":
                        form = UserDefines.First(x => x.Name == "0元列管入库单");
                        sourceType = 57;
                        break;
                    case "MTR":
                        form = UserDefines.First(x => x.Name == "批量调拨单");
                        sourceType = 59;
                        break;
                }
                formId = form!.Id;
                //更新自定义主单
                UpdataMainFormPush(data, form, sourceType);
                //更新记录推送状态表单
                UpdateCustomerForm(data);


                //流程完结的时候取审批记录
                if (data.status == 3 || data.status == 7 || data.status == 6)
                {


                   
                    List<ProcessList> processLists = YideaClient.GetProcessByKeyWord(new QueryParam() { FilterString = $"taskState=1&billNo={data.billNo}" }).ToList();
                    if(processLists.Count==0)
                       _logger.LogInformation("审批单据找不到：" + data.billNo);
                    if (processLists.Count > 0)
                    {
                        var processList = processLists[0];
                        RunnersItem runnersItem = new RunnersItem() { TaskId = processList.Id, ProcessInstanceId = processList.ProcessInstanceId };
                        _logger.LogInformation("审批参数：taskid" + processList.Id + ",ProcessInstanceId=" + processList.ProcessInstanceId);
                        if (data.status == 6)
                        {
                            bool processResult = YideaClient.RunProcessBatch(new ApproveModel() { Runners = new List<RunnersItem>() { runnersItem } });
                            _logger.LogInformation("单据：" + data.billNo + "审批通过结果：" + processResult);
                        }
                        else
                        {
                            bool processResultBoHui = YideaClient.RefuseProcessBatch(new ApproveModel() { Runners = new List<RunnersItem>() { runnersItem } });
                            Thread.Sleep(60000);
                            //bool processResultHuiTui = YideaClient.SendBackProcess(Guid.Parse("76c4f7f9-73e0-11ea-895d-35a25c906031"), runnersItem.ProcessInstanceId,formId,runnersItem.TaskId,data.suggestion);
                            _logger.LogInformation("单据：" + data.billNo + "审批驳回结果：" + processResultBoHui);
                            //_logger.LogInformation("单据：" + data.billNo + "审批回退结果：" + processResultHuiTui);
                        }
                    }
                    _logger.LogInformation("获取日志");
                   GetAuditLog(data, form, sourceType);

                }
            }
        }

        private void UpdataMainFormPush(UpdateBillModel data, UserDefine form, int sourceType)
        {
            _logger.LogInformation("UpdataMainFormPush：" + data.billNo);
            try
            {
                if (!IsNotPush)
                {
                    _logger.LogInformation("是否更新1");
                    CustomizedFormData customizedFormData1 = new CustomizedFormData();
                    customizedFormData1.FormId = form!.Id;
                    customizedFormData1.WebhookPush = false;
                    customizedFormData1.SerialNo = data.billNo;
                    JsonObject customizedData1 = new JsonObject();
                    var pushStateField = ExtendFields.First(x => x.ObjectType == sourceType && x.Name == "推送状态");
                    JsonObject stateValue = new JsonObject();
                    stateValue.Add("value", data.status);
                    customizedData1.Add(pushStateField.FieldId, stateValue);
                    var reasonField = ExtendFields.First(x => x.ObjectType == sourceType && x.Name == "失败原因");
                    JsonObject reasonValue = new JsonObject();
                    reasonValue.Add("value", data.suggestion);
                    customizedData1.Add(reasonField.FieldId, reasonValue);
                    customizedFormData1.Data = customizedData1;
                    var updateResponse1 = YideaClient.UpdateCustomizedFormData(customizedFormData1, null);
                    _logger.LogInformation("UpdataMainFormPush结果：" + updateResponse1);
                }
            }
            catch (Exception ex) {

                _logger.LogInformation("UpdataMainFormPush error：" + ex.ToString());
            }
        }

        private void UpdateCustomerForm(UpdateBillModel data)
        {
            _logger.LogInformation("UpdateCustomerForm:"+data.billNo);
            try
            {
                //if (!IsNotPush)
                //{
                var customForm = UserDefines.First(x => x.Name == "单据状态记录");
                //取billno对应的自定义表单
                var billField = ExtendFields.First(x => x.ObjectType == 0 && x.Name == "billno");
                List<UserDefinedForm> userdefinedList = YideaClient.GetUserDefinedForms(customForm.Id, new QueryParam() { FilterString = "[{\"field\":\"" + billField.FieldId + "\",\"type\":\"input\",\"label\":\"billno\",\"opt\":\"Equal\",\"val\":\"" + data.billNo + "\"}]" }).ToList();
                //更新自定义表单同步状态
                var userdefined = userdefinedList[0];
                CustomizedFormData customizedFormData = new CustomizedFormData();
                customizedFormData.FormId = userdefined.FormId ?? Guid.Empty;
                customizedFormData.SerialNo = userdefined.SerialNo!;
                JsonObject customizedData = new JsonObject();
                var stateField = ExtendFields.First(x => x.ObjectType == 0 && x.Name == "state");
                var stateFieldValue = new JsonObject
                {

                    ["value"] = data.status

                };
                customizedData.Add(stateField.FieldId, stateFieldValue);
                customizedFormData.Data = customizedData;
                var updateResponse = YideaClient.UpdateCustomizedFormData(customizedFormData, null);
                _logger.LogInformation("UpdateCustomerForm结果：" + updateResponse);
                //}
            }
            catch (Exception ex) {

                _logger.LogInformation("UpdateCustomerForm error:" + ex.ToString());
            }
        }

        private void GetAuditLog(UpdateBillModel data, UserDefine form, int sourceType)
        {
            if (!IsNotPush)
            {
                var customForm = UserDefines.First(x => x.Name == "单据状态记录");
                var billField = ExtendFields.First(x => x.ObjectType == 0 && x.Name == "billno");
                List<UserDefinedForm> userdefinedList = YideaClient.GetUserDefinedForms(customForm.Id, new QueryParam() { FilterString = "[{\"field\":\"" + billField.FieldId + "\",\"type\":\"input\",\"label\":\"billno\",\"opt\":\"Equal\",\"val\":\"" + data.billNo + "\"}]" }).ToList();
                //更新自定义表单同步状态
                var userdefined = userdefinedList[0];
                var createdByNo = userdefined.CreatedByNo!.ToString();
                JsonObject result = FromClient.GetData(new JsonObject
                {
                    ["billNo"] = data.billNo.ToString(),
                    ["procInstId"] = data.procInstId,
                    ["operateUserId"] = createdByNo
                });
                _logger.LogInformation("GetData:" + result["code"].ToString());
                if (result["code"].ToString() == "000000")
                {
                    var approvalList = result["result"]!.AsArray();
                    CustomizedFormData flowStateForm = new CustomizedFormData();
                    flowStateForm.FormId = form!.Id;
                    flowStateForm.WebhookPush = false;
                    flowStateForm.SerialNo = data.billNo;
                    JsonObject customizedFlowStateData = new JsonObject();
                    var logTableField = ExtendFields.First(x => x.ObjectType == sourceType && x.Name == "审批日志");
                    var approverField = ExtendFields.First(x => x.ObjectType == sourceType && x.Name == "审批人");
                    var suggestionField = ExtendFields.First(x => x.ObjectType == sourceType && x.Name == "审批意见");
                    var timeField = ExtendFields.First(x => x.ObjectType == sourceType && x.Name == "审批时间");
                    var item = new JsonArray();
                    foreach (var approval in approvalList)
                    {
                        var suggestion = approval!["suggestion"]!.GetValue<string>();
                        suggestion = HtmlParse.NoHtml(suggestion);
                        item.Add(new JsonObject
                        {
                            [approverField.FieldId] = new JsonObject { ["value"] = approval!["userName"]!.GetValue<string>() },
                            [suggestionField.FieldId] = new JsonObject { ["value"] = suggestion },
                            [timeField.FieldId] = new JsonObject { ["value"] = approval!["createDate"]!.GetValue<string>() },
                        });
                    }

                    var tableFieldValue = new JsonObject
                    {
                        [logTableField.FieldId] = item
                    };
                    flowStateForm.Data = tableFieldValue;
                    var updateTableResponse = YideaClient.UpdateCustomizedFormData(flowStateForm, null);
                    _logger.LogInformation("更新自定义单据审批记录：" + updateTableResponse);

                }
                else
                {
                    Logger.Error($"获取审核日志失败：billno:{data.billNo}-procInstId:{data.procInstId}-operateUserId:{createdByNo}-error:{result["message"]}");
                }
            }
        }
    }
    }
